home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 11
/
CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso
/
cucd
/
graphics
/
mpimage
/
si
/
miscmpi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-14
|
15KB
|
656 lines
// MPImage - Amiga Image Conversion
// Copyright (C) © 1996 Mark John Paddock
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mark@topic.demon.co.uk
// mpaddock@cix.compulink.co.uk
/****** MPImage.library/--background-- ******************************
*
* Version 7.3 - fixed enforcer hit when no progress requester.
* - Opens locale.library(38) to work on OS3.0.
*
* MPImage.library lets you load save and process images.
*
* Stuctures/Formats:
*
* RGB Chunky This is held as seperate Red Green and Blue
* UBYTE *, with a Width and Height
* Grey Chunky This is held as one Grey UBYTE * (often called
* red), with a Width and a Height.
* Palette This is held as one UBYTE[768] (sometimes called
* red, a Width and Height, and a UBYTE *Palette. The
* palette holds the red palette in [0] to [255],
* the green palette in [256] to [511] and the blue
* palette in [512] to [767]. There may also be a
* camg (or modeid) and a number of colours, or
* number of planes. These are required for EHB and
* HAM images.
* Bitmap A normal planar bit map. This also has other
* fields as for Palette.
* EGSBitMap A standard EGSBitMap.
* MPImage This holds one of RGB, Grey, Bitmap or EGSBitMap.
* MPProcess This holds the RGB pointers and width and height.
* It is used for some processing functions.
*
* Image Loading:
*
* LoadMPImage() Loads an image from disc/clipboard.
* It loads various formats.
* Returns BitMap, RGB, GreyScale or EGSBitMap.
*
* Image Saving:
*
* SaveMPImage() Can save RGB/GreyScale to disc.
* It saves in various formats.
*
* ImageScaling:
*
* RescaleMPImage() Scales a loaded image (any format).
*
* Displaying Images
*
* SaveMPImage() Can display RGB/GreyScale Buffers.
*
* Miscellaneous:
*
* FreeMPImage() Frees a loaded image.
* SetMPImageScreen() Sets the screen for the progress requester.
* MPProgressHook() Sets a progress hook for messages.
* MPImageErrorMessage() Returns the last error message.
*
* Planar/Chunky Conversion:
*
* MPPlanarToChunky() Converts a BitMap to a chunky buffer.
* MPChunkyToPlanar() Converts a chunky buffer to a BitMap.
* SaveMPImage() Can convert RGB Buffers to a BitMap.
*
* Image processing:
*
* Image processing is done on chunky buffers; RGB, GreyScale
* or Palette based. The following convert between these formats.
*
* MPGreyToPal() GreyScale to Palette.
* MPPalToGrey() Palette to GreyScale.
* MPPalToPal() Palette to a different Palette.
* MPPalToRGB() Palette to RGB.
* MPRGBToGrey() RGB To Grey.
* MPRGBToPal() RGB To Palette.
*
* Buffers can also be scaled:
*
* MPScaleGrey() Scales one buffer.
* MPScaleRGB() Scales 3 buffers.
* Same as 3 calls to MPScaleGrey() but faster.
*
* Summary:
*
* Input Output Format
* Format !Disc! RGB !Gray !Palette!BitMap!EGSBitMap!MPImage!Screen
* ---------!----!-----!-----!-------!------!---------!-------!------
* Disc/Clip! !1* !1* ! !1* !1* !1 !
* RGB !2 !13,3*!10 !11 !2 ! ! !2
* Gray !2 !x !12,3*!6 !2 ! ! !2
* Palette ! !9 !7 !8 !5 ! ! !
* BitMap ! ! ! !4 !3*,o ! ! !
* EGSBitMap! ! ! ! ! !3* ! !
* MPImage !2+ !+ !+ !# !+ !+ !3 !2+
*
* 1 - LoadMPImage()
* 2 - SaveMPImage()
* 3 - RescaleMPImage()
* 4 - MPPlanarToChunky()
* 5 - MPChunkyToPlanar()
* 6 - MPGreyToPal()
* 7 - MPPalToGrey()
* 8 - MPPalToPal()
* 9 - MPPalToRGB()
* 10 - MPRGBToGrey()
* 11 - MPRGBToPal()
* 12 - MPScaleGrey()
* 13 - MPScaleRGB()
* * - As part of an MPImage
* + - Depends on parameters to LoadMPImage
* x - Easy - no function supplied
* o - See BitMapScale()
* # - Depends on LoadMPImage, use 11,6,8 or 4
*
*****************************************************************************
*
*/
#define CATCOMP_BLOCK
#define CATCOMP_NUMBERS
#include "messages.h"
#include "mpimage.h"
extern struct Catalog *Catalog=NULL;
extern struct Library *LocaleBase = NULL;
extern struct Library *DCTVBase = NULL;
#ifdef CYBER
extern struct Library *CyberGfxBase = NULL;
#endif
extern struct Library *EGSBase = NULL;
extern char ErrorMessage[256] = "";
extern long __oslibversion=39;
const char Version[]="$VER: MPImage.library"
#ifdef MY040
"_040"
#else
#ifdef _M68060
"_060"
#else
#ifdef _M68881
"_881"
#else
#ifdef _M68020
"_020"
#else
"_000"
#endif
#endif
#endif
#endif
" 7.5 (14.3.97)";
char
*GetMg(UWORD message) {
LONG *l;
UWORD *w;
STRPTR builtIn;
l = (LONG *)CatCompBlock;
while (*l != message) {
w = (UWORD *)((ULONG)l + 4);
l = (LONG *)((ULONG)l + (ULONG)*w + 6);
}
builtIn = (STRPTR)((ULONG)l + 6);
return(GetCatalogStr(Catalog,message,builtIn));
}
static far int OpenCount = 0;
static far struct SignalSemaphore sema = {0};
static struct Hook *ProgressHook = NULL;
extern void
SetMax(int max) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Progress],ProgressWnd,NULL,
GTSL_Max,max-1,
GTSL_Level,0,
TAG_END);
}
if (ProgressHook) {
CallHookPkt(ProgressHook,MPIP_MAX,(APTR)max);
}
}
extern void
SetCur(int cur) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Progress],ProgressWnd,NULL,
GTSL_Level,cur,
TAG_END);
}
if (ProgressHook) {
CallHookPkt(ProgressHook,MPIP_CURR,(APTR)cur);
}
}
void AddMessageNo(UWORD no) {
AddMessage(GetMg(no));
}
int top = 0;
// add a message to the progress list
void
AddMessage(UBYTE *message) {
struct Node *node;
if (ProgressWnd) {
if ((node = (struct Node *)malloc(sizeof(struct Node))) &&
(node->ln_Name = malloc(strlen(message)+1))) {
strcpy(node->ln_Name,message);
GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
GTLV_Labels, ~0,
TAG_END);
AddTail(&InfoList,node);
GT_SetGadgetAttrs(ProgressGadgets[GDX_Info],ProgressWnd,NULL,
GTLV_Labels, &InfoList,
GTLV_MakeVisible, top,
TAG_END);
top++;
}
HandleProgressIDCMP();
}
if (ProgressHook) {
CallHookPkt(ProgressHook,MPIP_MESSAGE,(APTR)message);
}
}
int __stdargs
_STI_CreateSema(void) {
#ifdef CYBER
char buffer[3];
#endif
Forbid();
if (!OpenCount) {
memset(&sema,0,sizeof(sema));
InitSemaphore(&sema);
NewList(&InfoList);
}
++OpenCount;
Permit();
if (!(LocaleBase = OpenLibrary("locale.library",38))) {
return 1;
}
Catalog = OpenCatalog(NULL,
"mp/mpimage.catalog",
TAG_END);
DCTVBase = OpenLibrary("dctv.library",3);
#ifdef CYBER
if (GetVar("mpimage/cybergraphics",buffer,1,0) != -1) {
CyberGfxBase = OpenLibrary("cybergraphics.library",40);
}
#endif
return 0;
}
void __stdargs
_STD_DeleteSema(void) {
--OpenCount;
if (LocaleBase) {
CloseCatalog(Catalog);
Catalog = NULL;
CloseLibrary(LocaleBase);
LocaleBase = NULL;
}
if (DCTVBase) {
CloseLibrary(DCTVBase);
DCTVBase = NULL;
}
#ifdef CYBER
if (CyberGfxBase) {
CloseLibrary(CyberGfxBase);
CyberGfxBase = NULL;
}
#endif
return;
}
extern void LockSema(void) {
ObtainSemaphore(&sema);
}
extern void UnlockSema(void) {
ReleaseSemaphore(&sema);
}
extern void
PlanarToChunky(struct p2cStruct *p2c) {
AddMessageNo(MSG_P2C);
ObtainSemaphore(&sema);
PlanarToChunkyAsm(p2c);
ReleaseSemaphore(&sema);
}
extern void
ChunkyToPlanar(struct c2pStruct *c2p) {
AddMessageNo(MSG_C2P);
ObtainSemaphore(&sema);
ChunkyToPlanarAsm(c2p);
ReleaseSemaphore(&sema);
}
/****** MPImage.library/MPChunkyToPlanar ******************************
*
* NAME
* MPChunkyToPlanar -- Convert a chunky buffer to a BitMap (V7)
*
* SYNOPSIS
* MPChunkyToPlanar( chunky, bitmap, width, height )
* A0 A1 D0 D1
*
* void MPPlanarToChunky( UBYTE *, struct BitMap *, UWORD, UWORD);
*
* FUNCTION
* Converts a chunky buffer to a BitMap.
*
* INPUTS
* chunky - Pointer to a chunky buffer of sufficient size.
* bitmap - Pointer to a standard bitmap (of sufficient size).
* width - Width of buffer.
* height - Height of buffer.
*
* RESULT
* None.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
* MPPlanarToChunky().
*
*****************************************************************************
*
*/
void __asm __saveds
MPChunkyToPlanar(register __a0 UBYTE *chunky,register __a1 struct BitMap *bitmap,
register __d0 UWORD width, register __d1 UWORD height) {
struct c2pStruct c2p;
c2p.bmap = bitmap;
c2p.startX = 0;
c2p.startY = 0;
c2p.width = width;
c2p.height = height;
c2p.chunkybuffer = chunky;
ObtainSemaphore(&sema);
ChunkyToPlanarAsm(&c2p);
ReleaseSemaphore(&sema);
}
struct MyBitMap *
MyAllocBitMap(UWORD wide,UWORD high, UWORD deep, UBYTE *filename) {
struct MyBitMap *bitmap;
int k;
BOOL error = 0;
if (!filename || !*filename) {
return (struct MyBitMap *)AllocBitMap(wide,high,deep,BMF_CLEAR|BMF_DISPLAYABLE,NULL);
}
if (bitmap = AllocMem(sizeof(struct MyBitMap),MEMF_CLEAR)) {
InitBitMap((struct BitMap *)bitmap,deep,wide,high);
for (k=0; k<deep && (!error); k++) {
if (!(bitmap->BitMap.Planes[k] = AllocVec(RASSIZE(wide,high),MEMF_CLEAR))) {
error = 1;
}
}
if(error) {
MyFreeBitMap(bitmap,filename);
bitmap = NULL;
}
}
return bitmap;
}
void
MyFreeBitMap(struct MyBitMap *bitmap,UBYTE *filename) {
int k;
if (!filename || !*filename) {
FreeBitMap(bitmap);
return;
}
for(k=0; k< bitmap->BitMap.Depth; k++) {
if (bitmap->BitMap.Planes[k]) {
FreeVec(bitmap->BitMap.Planes[k]);
}
}
FreeMem(bitmap,sizeof(struct MyBitMap));
}
void __asm __saveds FreeMPImage(register __a0 struct MPImage *MPi);
char * __asm __saveds MPImageErrorMessage(void);
/****** MPImage.library/MPPlanarToChunky ******************************
*
* NAME
* MPPlanarToChunky -- Convert a bitmap to a chunky buffer (V5)
*
* SYNOPSIS
* MPPlanarToChunky( bitmap, chunky, width, height )
* A0 A1 D0 D1
*
* void MPPlanarToChunky( struct BitMap *, UBYTE *, UWORD, UWORD);
*
* FUNCTION
* Converts a BitMap to a chunky buffer.
*
* INPUTS
* bitmap - Pointer to a standard bitmap.
* chunky - Pointer to a chunky buffer of sufficient size.
* width - Width of bitmap.
* height - Height of bitmap.
*
* RESULT
* None.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
* MPChunkyToPlanar().
*
*****************************************************************************
*
*/
void __asm __saveds
MPPlanarToChunky(register __a0 struct BitMap *bitmap,register __a1 UBYTE *chunky,
register __d0 UWORD width, register __d1 UWORD height) {
struct p2cStruct p2c;
p2c.bmap = bitmap;
p2c.startX = 0;
p2c.startY = 0;
p2c.width = width;
p2c.height = height;
p2c.chunkybuffer = chunky;
ObtainSemaphore(&sema);
PlanarToChunkyAsm(&p2c);
ReleaseSemaphore(&sema);
}
/****** MPImage.library/FreeMPImage ***********************************
*
* NAME
* FreeMPImage -- Free an image loaded using LoadMPImage() (V3)
*
* SYNOPSIS
* FreeMPImage( MPi )
* A0
*
* void FreeMPImage( struct MPImage * );
*
* FUNCTION
* Frees all data associated loaded with an image using LoadMPImage().
*
* INPUTS
* MPi - structure returned by LoadMPImage().
*
* RESULT
* None.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
* LoadMPImage()
*
*****************************************************************************
*
*/
void __asm __saveds
FreeMPImage(register __a0 struct MPImage *MPi) {
if (MPi) {
if (MPi->Red) {
FreeVec(MPi->Red);
}
if (!MPi->GreyScale) {
if (MPi->Blue) {
FreeVec(MPi->Blue);
}
if (MPi->Green) {
FreeVec(MPi->Green);
}
}
if (MPi->Object) { // Dispose object (frees bit map as well...)
DisposeDTObject(MPi->Object);
}
else {
if (MPi->BitMap) {
FreeBitMap(MPi->BitMap);
}
if (MPi->EGS_BitMap) {
if (EGSBase = OpenLibrary((char *)"egs.library",0)) {
E_DisposeBitMap(MPi->EGS_BitMap);
CloseLibrary(EGSBase);
}
}
}
FreeMem(MPi,sizeof(struct MPImage));
}
}
/****** MPImage.library/MPImageErrorMessage *********************************
*
* NAME
* MPImageErrorMessage -- Return the last error set by MPImage.library. (V3)
*
* SYNOPSIS
* msg = MPImageErrorMessage()
* D0
*
* char *MPImageErrorMessage( void );
*
* FUNCTION
* Returns the last error message set by this opener of MPImage.library.
*
* INPUTS
* None.
*
* RESULT
* Formatted Error Message.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
*
*****************************************************************************
*
*/
char * __asm __saveds
MPImageErrorMessage(void) {
return ErrorMessage;
}
extern BOOL ShowProgress;
/****** MPImage.library/SetMPImageScreen ************************************
*
* NAME
* SetMPImageScreen -- Sets the Screen name for progress requesters (V3)
*
* SYNOPSIS
* SetMPImageScreen(ScreenName,Flags)
* A0 D0
*
* void SetMPImageScreen(char *, ULONG);
*
* FUNCTION
* Sets the Screen Name for progress requesters for this opener.
*
* INPUTS
* ScreenName - Name of Public Screen, NULL for default
* Flags - 0 - Do not show progress requesters (default)
* - MPIF_PROGRESS - Do show progress requesters
* (except for non remapped bitmaps).
*
* RESULT
* None.
*
* EXAMPLE
*
* NOTES
* ScreenName must remain valid while MPImage.library is open.
*
* BUGS
*
* SEE ALSO
*
*****************************************************************************
*
*/
void __asm __saveds
SetMPImageScreen(register __a0 char *ScreenName, register __d0 ULONG Flags) {
PubScreenName = ScreenName;
if (Flags & MPIF_PROGRESS) {
ShowProgress = TRUE;
}
else {
ShowProgress = FALSE;
}
}
/****** MPImage.library/MPProgressHook ************************************
*
* NAME
* MPProgressHook -- Sets the Progress Hook (V6)
*
* SYNOPSIS
* MPProgressHook(Hook)
* A0
*
* void MPProgressHook(struct Hook*);
*
* FUNCTION
* Sets the Hook to call for progress messages.
*
* INPUTS
* Hook - Hook to call
*
* RESULT
* None.
*
* EXAMPLE
*
* NOTES
* Called with...
* object = MPIP_MAX, (ULONG)message = max-progress
* object = MPIP_MAX, (ULONG)message = curr-progress
* object = MPIP_CURR,(UBYTE *)message = Progress-Message
*
* BUGS
*
* SEE ALSO
*
*****************************************************************************
*
*/
void __asm __saveds
MPProgressHook(register __a0 struct Hook *Hook) {
ProgressHook = Hook;
}